/*
 * MixerMissionManager.cpp
 *
 *  Created on: Nov 28, 2013
 *      Author: wyf
 */

#include <MixerMissionManager.h>

MixerMissionManager::MixerMissionManager() {
}

MixerMissionManager::~MixerMissionManager() {
}

bool MixerMissionManager::addRecMission(DWORD roomid, DWORD recid, DWORD sttime, DWORD endtime, const char *path) {
	Zebra::logger->info("----[xuhui]addRecMission roomid(%u), recid(%u)", roomid, recid);
	rwlock_.wrlock();
	TM_CIT it = mission_map_.find(roomid);
	if (it != mission_map_.end()) {
		rwlock_.unlock();
		return false;
	}

	MixerMission* mission;
	if (0 != MixerMission::Create(mission, roomid, recid, sttime, endtime, path)) {
		rwlock_.unlock();
		return false;
	}
	mission_map_.insert(TM_VT(roomid, mission));
	rwlock_.unlock();
	return true;
}

void MixerMissionManager::delRecMission(DWORD roomid) {
	rwlock_.wrlock();
	TM_IT it = mission_map_.find(roomid);
	if (it != mission_map_.end()) {
		MixerMission *mission = it->second;
		if (mission == NULL) {
			Zebra::logger->info("----[xuhui]when del rec mission, mission is null");
		}
		else {
			Zebra::logger->info("----[xuhui]del rec mission roomid(%u), recid(%u)", mission->getRoomId(), mission->getRecId());
			MixerMission::Destroy(mission);
			mission = NULL;
		}
		mission_map_.erase(it);
	}
	rwlock_.unlock();
}

void MixerMissionManager::updateRecTime(DWORD roomid, DWORD sttime, DWORD endtime) {
	rwlock_.wrlock();
	TM_IT it = mission_map_.find(roomid);
	if (it != mission_map_.end()) {
		it->second->updateMissionTime(sttime, endtime);
	}
	rwlock_.unlock();
}

void MixerMissionManager::delTimeOutMission(DWORD curtime) {
	rwlock_.wrlock();
	TM_IT it = mission_map_.begin();
	for (; it != mission_map_.end();) {
		MixerMission *mission = it->second;
		if (mission == NULL) {
			Zebra::logger->info("----[xuhui]when del timeout mission, mission is null");
			mission_map_.erase(it++);
		}
		else {
			if (mission->isTimeOut(curtime)) {
				Zebra::logger->info("----[xuhui]del timeout mission roomid(%u), recid(%u)", mission->getRoomId(), mission->getRecId());
				mission_map_.erase(it++);
				MixerMission::Destroy(mission);
				mission = NULL;
			}
			else {
				it++;
			}
		}
	}
	rwlock_.unlock();
}

void MixerMissionManager::memberJoinRoom(DWORD roomid, DWORD userid) {
	Zebra::logger->debug("----[xuhui]memberJoinRoom roomid(%u), userid(%u)", roomid, userid);
	UDPPacket* tmp = new UDPPacket(2, (BYTE*) &userid, sizeof(DWORD));
	disPatchPacket(roomid, tmp);
}

void MixerMissionManager::memberLeaveFromRoom(DWORD roomid, DWORD userid) {
	Zebra::logger->debug("----[xuhui]memberLeaveFromRoom roomid(%u), userid(%u)", roomid, userid);
	UDPPacket* tmp = new UDPPacket(3, (BYTE*) &userid, sizeof(DWORD));
	disPatchPacket(roomid, tmp);
}

void MixerMissionManager::onAudioPacket(uint8_t* buf, DWORD len) {
	// Zebra::logger->debug("----[xuhui]onAudioPacket len(%u), type(%u)", len, rev->proto_type_);
	// if (rev->proto_type_ == eUDPProtoType_RTP) {
	AudioCmd::stUDPPkgHead *rev = reinterpret_cast<AudioCmd::stUDPPkgHead *>(buf);
	UDPPacket* tmp = new UDPPacket(0, buf, len);
	disPatchPacket(rev->room_id_, tmp);
	/*} else if (rev->proto_type_ == eUDPProtoType_RTCP) {
	  UDPPacket* tmp = new UDPPacket(1, buf, len);
	  disPatchPacket(rev->room_id_, tmp);
	  }*/

}

void MixerMissionManager::disPatchPacket(DWORD roomid, UDPPacket* pack) {
	rwlock_.wrlock();
	bool stored = false;
	TM_CIT it = mission_map_.find(roomid);
	if (it != mission_map_.end()) {
		if (NULL != it->second) {
			it->second->onRtpPacket(pack);
			stored = true;
		}
		else {
			Zebra::logger->debug("----[xuhui]dispatch room(%u) mission ptr is null", roomid);
		}
	}
	else {
		//Zebra::logger->debug("----[xuhui]dispatch room(%u) is not exist", roomid);
	}
	if (!stored && pack) {
		delete pack;
	}
	rwlock_.unlock();
}

void MixerMissionManager::getAudioPacket(t_BufferCmdQueue &to) {
	rwlock_.wrlock();
	TM_IT it = mission_map_.begin();
	for (; it!= mission_map_.end(); it++) {
		if (NULL != it->second) {
			t_BufferCmdQueue tmp;
			it->second->getAudioPacket(tmp);
			to.put(tmp.rd_buf(), tmp.rd_size());
		}
	}
	rwlock_.unlock();
}

void MixerMissionManager::addMuteData(const uint8_t *data, const DWORD &len)
{
	rwlock_.wrlock();
	for (TM_IT it = mission_map_.begin(); it != mission_map_.end(); it++) {
		if (NULL != it->second) {
			it->second->addMute(data, len);
		}
	}
	rwlock_.unlock();
}

